import 'dart:convert';

import 'package:common_utils/common_utils.dart';
import 'package:encrypt/encrypt.dart';
import 'package:rsa_encrypt/rsa_encrypt.dart';
import 'package:yuan_hang_app/res/w_constant.dart';

class StringUtils {
  ///大陆手机号码11位数，匹配格式：前三位固定格式+后8位任意数
  /// 此方法中前三位格式有：
  /// 13+任意数 * 15+除4的任意数 * 18+除1和4的任意数 * 17+除9的任意数 * 147
  static bool isChinaPhoneLegal(String str) {
    return RegExp(
        '^1[3-9]\\d{9}\$')
        .hasMatch(str);
    // return RegExp(
    //         '^((13[0-9])|(15[^4])|(166)|(17[0-8])|(18[0-9])|(19[8-9])|(147,145))\\d{8}\$')
    //     .hasMatch(str);
  }

//密码验证
   static bool validatePassword(String password) {
    // 检查长度
    if (password.length < 8 || password.length > 32) {
      return false;
    }
    // 定义正则表达式来检查不同类型的字符
    RegExp digitPattern = RegExp(r'\d');
    RegExp lowerCasePattern = RegExp(r'[a-z]');
    RegExp upperCasePattern = RegExp(r'[A-Z]');
    RegExp specialCharPattern = RegExp(r'[!@#$%^&*(),.?":{}|<>]'); // 示例特殊字符集
    // 检查是否包含至少一个数字、一个小写字母、一个大写字母和一个特殊字符
    bool hasDigit = digitPattern.hasMatch(password);
    bool hasLowerCase = lowerCasePattern.hasMatch(password);
    bool hasUpperCase = upperCasePattern.hasMatch(password);
    bool hasSpecialChar = specialCharPattern.hasMatch(password);

    // 确保密码包含至少三种类型的字符
    int validTypes = 0;
    if (hasDigit) validTypes++;
    if (hasLowerCase) validTypes++;
    if (hasUpperCase) validTypes++;
    if (hasSpecialChar) validTypes++;
    return validTypes >= 3;
  }


  // 邮箱判断
  static bool isEmail(String str) {
    String regexEmail =
        "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}\$";
    return RegExp(regexEmail).hasMatch(str);
  }

  // 证件号是否是 字母和数字
  static bool isCardNumber(String input) {
    String letterDigitRegex = "^[a-z0-9A-Z]+\$";
    return RegExp(letterDigitRegex).hasMatch(input);
  }

  // 是否是正整数数字
  static bool isAge(String input) {
    String letterDigitRegex = "^((1[0-5])|[1-9])?\\d\$";
    return RegExp(letterDigitRegex).hasMatch(input);
  }

  static bool isRightPrice(String input) {
    String letterDigitRegex = "^[1-9][0-9]{0,7}\$";
    return RegExp(letterDigitRegex).hasMatch(input);
  }

  static bool isEmpty(value) {
    if (value == null ||
        value.toString().isEmpty ||
        value == "" ||
        value == 'null' ||
        value.toString() == '0') {
      return true;
    }
    return false;
  }

  static bool isEmpty2(value) {
    if (value == null || value.toString().isEmpty || value == "" || value == 'null') {
      return true;
    }
    return false;
  }

  /// 安全取出map值(String)
  static String safeGetMap(item, key, {placehoder = ''}) {
    if (item == null || item.isEmpty) return placehoder;
    var value = item[key];
    if (value == null ||
        value.toString().isEmpty ||
        value == 'null' ||
        value.toString() == '0') {
      return placehoder;
    }
    return value.toString();
  }

  /// 安全取出map值(String2)
  static String safeGetMapKeys(Map item, String key,
      {String placeHolder = ''}) {
    if (item.isEmpty) return placeHolder;
    String result = placeHolder;
    if (item.containsKey(key)) {
      result = safeGetMap(item, key, placehoder: placeHolder);
    } else {
      item.forEach((k, value) {
        if (value is Map && result == placeHolder) {
          result = safeGetMapKeys(value, key, placeHolder: placeHolder);
        }
      });
    }
    return result;
  }

  static bool compareDate(
    String str,
  ) {
    DateTime compareDate = DateTime.parse(str);
    if (compareDate.isAfter(DateTime.now())) {
      return true;
    }
    return false;
  }

  static String handelTheTimeStrFormatEndMM(String str,
      {bool endToDD = false}) {
    if (str.length < 19) return str;
    return endToDD
        ? str.substring(0, str.length - 9)
        : str.substring(0, str.length - 3);
  }

  /// 安全取出值(String)
  static String safeGetValue(value, {placeHolder = ''}) {
    if (value == null ||
        value.toString().isEmpty ||
        value == 'null' ||
        value.toString() == '0' ||
        value == "") {
      return placeHolder;
    }
    return value.toString();
  }

  /// 处理手机号加* 不可见
  static String handleThePhoneStr(phoneNumber) {
    if (!isChinaPhoneLegal(phoneNumber)) {
      return phoneNumber;
    }
    String temp = '';
    for (var i = 0; i < phoneNumber.length; i++) {
      if (i > 2 && i < 7) {
        temp += '*';
      } else {
        temp += phoneNumber[i];
      }
    }
    return temp;
  }

  /// 处理他妈的其他各种证件加几把*号
  static String handleOtherCardAddx(String card) {
    if (card.length <= 2) {
      return card;
    }
    String temp = '';
    for (var i = 0; i < card.length; i++) {
      if (i > 0 && i < card.length - 1) {
        temp += '*';
      } else {
        temp += card[i];
      }
    }
    return temp;
  }

  /// 处理身份证号加*不可见
  static String handleTheidCardStr(idCard) {
    if (idCard.length < 18) return idCard;
    String temp = '';
    for (var i = 0; i < idCard.length; i++) {
      if (i > 5 && i < idCard.length - 4) {
        temp += '*';
      } else {
        temp += idCard[i];
      }
    }
    return temp;
  }

  /// 身份证号码验证
  static bool isCardId(String cardId) {
    if (cardId.length != 18) {
      return false; // 位数不够
    }
    // 身份证号码正则
    RegExp postalCode = RegExp(
        r'^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|[Xx])$');
    // 通过验证，说明格式正确，但仍需计算准确性
    if (!postalCode.hasMatch(cardId)) {
      return false;
    }
    //将前17位加权因子保存在数组里
    final List idCardList = [
      "7",
      "9",
      "10",
      "5",
      "8",
      "4",
      "2",
      "1",
      "6",
      "3",
      "7",
      "9",
      "10",
      "5",
      "8",
      "4",
      "2"
    ];
    //这是除以11后，可能产生的11位余数、验证码，也保存成数组
    final List idCardYArray = [
      '1',
      '0',
      '10',
      '9',
      '8',
      '7',
      '6',
      '5',
      '4',
      '3',
      '2'
    ];
    // 前17位各自乖以加权因子后的总和
    int idCardWiSum = 0;

    for (int i = 0; i < 17; i++) {
      int subStrIndex = int.parse(cardId.substring(i, i + 1));
      int idCardWiIndex = int.parse(idCardList[i]);
      idCardWiSum += subStrIndex * idCardWiIndex;
    }
    // 计算出校验码所在数组的位置
    int idCardMod = idCardWiSum % 11;
    // 得到最后一位号码
    String idCardLast = cardId.substring(17, 18);
    //如果等于2，则说明校验码是10，身份证号码最后一位应该是X
    if (idCardMod == 2) {
      if (idCardLast != 'x' && idCardLast != 'X') {
        return false;
      }
    } else {
      //用计算出的验证码与最后一位身份证号码匹配，如果一致，说明通过，否则是无效的身份证号码
      if (idCardLast != idCardYArray[idCardMod]) {
        return false;
      }
    }
    return true;
  }

  /// 处理身份证, 获取年龄
  static String getIdCardAgeFrom(String idCard) {
    if (isCardId(idCard)) {
      // 截取
      var year = idCard.substring(6, 10);

      /// 简单计算
      int age = DateTime.now().year - int.parse(year);
      if (age < 0) {
        return '';
      }
      return age.toString();
    } else {
      return '';
    }
  }

  /// 处理身份证, 获取出生年月
  static String getBirthdayFromId(String idCard) {
    if (isCardId(idCard)) {
      // 截取
      var year = idCard.substring(6, 10);
      var month = idCard.substring(10, 12);
      var day = idCard.substring(12, 14);
      return '$year-$month-$day';
    } else {
      return '';
    }
  }

  /// 获取性别
  static bool? isManFromIdCard(String idCard) {
    if (isCardId(idCard)) {
      var value = idCard.substring(16, 17);
      return int.parse(value) % 2 == 0 ? false : true;
    } else {
      return null;
    }
  }

  ///  返回时间戳
  static String readTimestamp(int timestamp) {
    var now = DateTime.now();
    var date = DateTime.fromMillisecondsSinceEpoch(timestamp);
    var diff = now.difference(date);
    var time = '';
    if (now.year == date.year &&
        now.month == date.month &&
        now.day == date.day) {
      time = DateUtil.formatDate(date, format: DateFormats.h_m);
    } else if (now.year == date.year &&
        now.month == date.month &&
        (now.day - date.day) == 1) {
      time = '昨天 ' + " " + DateUtil.formatDate(date, format: DateFormats.h_m);
    } else if (now.year == date.year &&
        now.month == date.month &&
        (now.day - date.day) > 1 &&
        (now.day - date.day) < 7) {
      // 星期几 ()
      Map temps = {1: "一", 2: "二", 3: '三', 4: '四', 5: '五', 6: '六', 7: '日'};
      time =
          "星期${temps[date.weekday]} ${DateUtil.formatDate(date, format: DateFormats.h_m)}";
    } else {
      time =
          " ${date.year.toString()}年${date.month.toString()}月${date.day.toString()}日${DateUtil.formatDate(date, format: DateFormats.h_m)}";
    }
    return time;
  }

  static Future<String> getRSAPassword(String data) async {
    const rsaPublicKey =
        '-----BEGIN RSA PUBLIC KEY-----\n${WConstant.encryptKey}\n-----END RSA PUBLIC KEY-----';
    final publicKey = await RsaKeyHelper().parsePublicKeyFromPem(rsaPublicKey);
    final encrypter = Encrypter(RSA(publicKey: publicKey));
    final encryptedText = encrypter.encrypt(data);
    return encryptedText.base64;
  }

  static String getFileIds(picList) {
    String files = "";
    for (int i = 0; i < picList.length; i++) {
      if (i == picList.length - 1) {
        files += picList[i].toString();
      } else {
        files += "${picList[i]},";
      }
    }
    return files;
  }

  static String secToTime(times) {
    String result = '00:00:00';
    result = DateUtil.formatDate(
        DateTime.fromMillisecondsSinceEpoch(times, isUtc: true),
        format: DateFormats.h_m_s);
    return result;
  }
}
